package com.lantosec.hmrp.modules.warning.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lantosec.hmrp.core.kit.PageVO;
import com.lantosec.hmrp.core.shiro.TokenUtil;
import com.lantosec.hmrp.modules.eval.entity.EvalItem;
import com.lantosec.hmrp.modules.eval.service.IEvalItemService;
import com.lantosec.hmrp.modules.system.service.ISysDeptService;
import com.lantosec.hmrp.modules.system.service.ISysDeptUserService;
import com.lantosec.hmrp.modules.system.service.ISysUserService;
import com.lantosec.hmrp.modules.warning.entity.*;
import com.lantosec.hmrp.modules.warning.mapper.WarningDataMapper;
import com.lantosec.hmrp.modules.warning.service.*;
import com.lantosec.hmrp.modules.warning.vo.WarningSummaryVO;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * <p>
 * 预警数据 服务实现类
 * </p>
 *
 * @author AutoCode
 * @since 2020-05-27
 */
@Service("WarningDataService")
@Primary
@Log4j2
@SuppressWarnings("all")
public class WarningDataServiceImpl extends ServiceImpl<WarningDataMapper, WarningData> implements IWarningDataService {

    @Autowired
    private IEvalItemService itemService;

    @Autowired
    private IWarningRuleService ruleService;

    @Autowired
    private IWarningEvalNoteService noteService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private IWarningNotifierService notifierService;

    @Autowired
    private IWarningReportedService reportedService;

    @Autowired
    private ISysDeptUserService deptUserService;

    @Override
    public Page<WarningSummary> summaryStatistics(PageVO<WarningSummary> page, WarningSummaryVO condition, Integer permissionsType) {
        PageVO<WarningSummary> param = baseMapper.summaryStatistics(page, condition);
        List<WarningSummary> warningData = getWarningData(param, permissionsType);
        return page.setRecords(warningData);
    }


    /**
     * @date: 2020-07-01 15:41
     * @instructions: 根据权限显示数据，
     * permissionsType = 1登录用户仅可查看自己需要处置的预警
     * permissionsType = 2仅可查看当前登录用户所属部门等于预警数据对应部门的数据
     * permissionsType = 3 全部数据
     * @param:
     * @return:
     */
    private List<WarningSummary> getWarningData(PageVO<WarningSummary> param, Integer permissionsType) {
        if (null == permissionsType) {
            permissionsType = 1;
        }
        List<WarningSummary> list = new ArrayList<>();
        String userId = TokenUtil.getUserId();
        String deptId = TokenUtil.getDeptId();
        if (permissionsType == 1) {
            param.getRecords().forEach(it -> {
                List<String> userList = getUserList(it);
                //去重
                HashSet set = new HashSet(userList);
                userList.clear();
                userList.addAll(set);
                userList.forEach(id -> {
                    if (StringUtils.isNotEmpty(id) && userId.contains(id)) {
                        list.add(it);
                    }
                });
            });
            return list;
        } else if (permissionsType == 3) {
            return param.getRecords();
        } else {
            List<WarningSummary> deptInfo = baseMapper.getDeptDataInfo(deptId);
            return deptInfo;
        }
    }

    private List getUserList(WarningSummary it) {
        List<String> result = new ArrayList();
        String ruleId = it.getRuleId();
        //查warning_notifier表通知对象
        List<WarningNotifier> notifierList = notifierService.list(new QueryWrapper<WarningNotifier>()
                .eq(String.valueOf(WarningNotifier.ColName.rule_id), ruleId));
        if (null != notifierList && notifierList.size() > 0) {
            List<String> notifierUserList = notifierUserList(ruleId, notifierList);
            notifierUserList.forEach(notifierUser->{
                result.add(notifierUser);
            });
        }
        //查warning_reported表通知对象
        List<WarningReported> reportedList = reportedService.list(new QueryWrapper<WarningReported>()
                .eq(String.valueOf(WarningNotifier.ColName.rule_id), ruleId));
        if (null != reportedList && reportedList.size() > 0) {
            List<String> reportedUserList = reportedUserList(ruleId, reportedList);
            reportedUserList.forEach(reportedUser->{
                result.add(reportedUser);
            });
        }
        return result;
    }

    private List<String> reportedUserList(String ruleId, List<WarningReported> reportedList) {
        List<String> result = new ArrayList();
        reportedList.forEach(reported -> {
            Integer notifierMode = reported.getNotifierMode();
            if (notifierMode == 1) {
                //部门下面所有人
                String notifierDeptId = reported.getNotifierDeptId();
                List<String> userIds = notifierService.getUserId(notifierDeptId);
                userIds.forEach(it->{
                    result.add(it);
                });
            } else if (notifierMode == 2) {
                //岗位下所有人
                List<String> userIds = baseMapper.getNotifierPositionId(ruleId);
                userIds.forEach(it->{
                    result.add(it);
                });
            } else if (notifierMode == 3) {
                //人员
                List<String> userIds = notifierService.getReportedUserList(ruleId);
                userIds.forEach(it->{
                    result.add(it);
                });
            } else if (notifierMode == 4) {
                //所有角色下所有人
                String notifierRoleId = reported.getNotifierRoleId();
                List<String> userIds = notifierService.getUserByRoleId(notifierRoleId);
                userIds.forEach(it->{
                    result.add(it);
                });
            }
        });
        return result;
    }

    private List<String> notifierUserList(String ruleId, List<WarningNotifier> notifierList) {
        List<String> result = new ArrayList();
        notifierList.forEach(notifier -> {
            Integer notifierMode = notifier.getNotifierMode();
            if (notifierMode == 1) {
                //部门下面所有人
                String notifierDeptId = notifier.getNotifierDeptId();
                List<String> userIds = notifierService.getUserId(notifierDeptId);
                userIds.forEach(it->{
                    result.add(it);
                });
            } else if (notifierMode == 2) {
                //岗位下所有人
                List<String> userIds = baseMapper.getNotifierPositionId(ruleId);
                userIds.forEach(it->{
                    result.add(it);

                });
            } else if (notifierMode == 3) {
                //人员
                List<String> userIds = notifierService.getUserList(ruleId);
                userIds.forEach(it->{
                    result.add(it);
                });
            } else if (notifierMode == 4) {
                //所有角色下所有人
                String notifierRoleId = notifier.getNotifierRoleId();
                List<String> userIds = notifierService.getUserByRoleId(notifierRoleId);
                userIds.forEach(it->{
                    result.add(it);
                });
            }
        });
        return result;
    }

    @Override
    public Page<WarningData> notHandle(PageVO<WarningData> page, String ruleId) {
        PageVO<WarningData> param = baseMapper.notHandle(page, ruleId);
        List<EvalItem> list = new ArrayList<>();
        List warningEval = getWarningEval(list, ruleId);
        if (null != warningEval && warningEval.size() > 0) {
            param.getRecords().forEach(it -> {
                it.setWarningRuleEvals(warningEval);
            });
        }
        return page.setRecords(param.getRecords());
    }

    private List getWarningEval(List<EvalItem> list, String ruleId) {
        List<WarningRuleEval> ruleEvals = baseMapper.selectWarningRuleEval(ruleId);
        if (null != ruleEvals && ruleEvals.size() > 0) {
            ruleEvals.forEach(it -> {
                String evalItemId = it.getEvalItemId();
                EvalItem item = itemService.getOne(new QueryWrapper<EvalItem>()
                        .eq(String.valueOf(EvalItem.ColName.eval_item_id), evalItemId));
                list.add(item);
            });
        }
        return list;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void create(List<WarningEvalNote> list) {
        String handleUserId = list.get(0).getHandleUserId();
        String handleUser = list.get(0).getHandleUser();
        String ruleId = list.get(0).getRuleId();
        Integer handleState = 4;
        WarningRule warningRule = ruleService.getOne(new QueryWrapper<WarningRule>()
                .eq(String.valueOf(WarningRule.ColName.rule_id), ruleId));
        Integer warningGrade = warningRule.getWarningGrade();
        //该条预警规则为三级预警，预警处置状态待审核
        if (warningGrade == 3) {
            handleState = 1;
        }
        for (WarningEvalNote it : list) {
            WarningData data = new WarningData();
            data.setHandleState(handleState);
            data.setHandleUserId(handleUserId);
            data.setHandleUser(handleUser);
            data.setHandleTime(new Date());
            org.springframework.beans.BeanUtils.copyProperties(it, data);
            //更新预警数据warning_data表
            baseMapper.updateById(data);
            //保存处置奖惩记录
            saveWarningEvalNote(it, it.getRewardType());

        }
    }

    private void saveWarningEvalNote(WarningEvalNote it, Integer rewardType) {
        List<WarningEvalNote> rewardArrList = it.getRewardArr();
        if (null != rewardArrList && rewardArrList.size() > 0) {
            String rewardArrJson = JSON.toJSONString(rewardArrList);
            List<WarningEvalNote> rewardArr = JSON.parseArray(rewardArrJson, WarningEvalNote.class);
            for (WarningEvalNote note : rewardArr) {
                WarningEvalNote evalNote = new WarningEvalNote();
                org.springframework.beans.BeanUtils.copyProperties(it, evalNote);
                BigDecimal rewardValue = note.getRewardValue();
                //奖惩值绝对值
                rewardValue = rewardValue.abs();
                //如果奖惩形式为奖，取rewardValue，为惩，取rewardValue相反数
                if (rewardType == 1) {
                    evalNote.setRewardValue(rewardValue);
                } else {
                    evalNote.setRewardValue(rewardValue.negate());
                }
                evalNote.setRewardType(rewardType);
                evalNote.setRewardOrientation(note.getRewardOrientation());
                //增加标识区分是app跟pc,null为pc,1为app
                if (null == note.getWarningFlag()) {
                    evalNote = getTarget(note, evalNote);
                } else {
                    evalNote = getTargetParam(note, evalNote);
                }
                noteService.save(evalNote);
            }
        }
    }

    private WarningEvalNote getTargetParam(WarningEvalNote note, WarningEvalNote evalNote) {
        String targetId = note.getTargetId();
        if (note.getTargetMode() == 2) {
            evalNote.setTargetId(targetId);
            evalNote.setTargetMode(2);
            evalNote.setTargetName(userService.getById(targetId).getName());
        } else {
            evalNote.setTargetId(targetId);
            evalNote.setTargetMode(1);
            evalNote.setTargetName(deptService.getById(targetId).getDeptName());
        }
        return evalNote;
    }

    private WarningEvalNote getTarget(WarningEvalNote note, WarningEvalNote evalNote) {
        String targetId = note.getTargetId();
        boolean contains = targetId.contains("-");
        if (contains) {
            String[] split = targetId.split("-");
            String userId = split[1];
            evalNote.setTargetId(userId);
            evalNote.setTargetMode(2);
            evalNote.setTargetName(userService.getById(userId).getName());
        } else {
            evalNote.setTargetId(targetId);
            evalNote.setTargetMode(1);
            evalNote.setTargetName(deptService.getById(targetId).getDeptName());
        }
        return evalNote;
    }

    @Override
    public Page<WarningData> hasDisposal(PageVO<WarningData> page, String ruleId, Integer warningFlag) {
        String remark = null;
        WarningRule warningRule = ruleService.getOne(new QueryWrapper<WarningRule>()
                .eq("rule_id", ruleId));
        PageVO<WarningData> data = baseMapper.selectPage(page, new QueryWrapper<WarningData>()
                .eq("rule_id", ruleId)
                .eq("handle_state", 3)
                .orderByDesc("handle_time"));
        data.getRecords().forEach(it -> {
            Integer dataId = it.getDataId();
            List<WarningEvalNote> notes = baseMapper.getWarningEvalNote(ruleId, dataId);
            notes.forEach(note -> {
                Integer targetMode = note.getTargetMode();
                if (targetMode == 2 && null == warningFlag) {
                    String targetId = note.getTargetId();
                    String deptId = baseMapper.queryDeptId(targetId);
                    note.setTargetId(deptId + "-" + targetId);
                } else if (targetMode == 2 && 1 == warningFlag) {
                    note.setTargetId(note.getTargetId());
                }
            });
            if (notes != null && notes.size() > 0) {
                it.setWarningEvalNotes(notes);
            }
            it.setTableDefine(warningRule.getTableDefine());
        });
        List<EvalItem> list = new ArrayList<>();
        List warningEval = getWarningEval(list, ruleId);
        if (null != warningEval && warningEval.size() > 0) {
            data.getRecords().forEach(it -> {
                it.setWarningRuleEvals(warningEval);
            });
        }
        return page.setRecords(data.getRecords());
    }

    @Override
    public Page<WarningData> disposalRejected(PageVO<WarningData> page, String ruleId) {
        List<EvalItem> list = new ArrayList<>();
        PageVO<WarningData> param = baseMapper.disposalRejected(page, ruleId);
        List warningEval = getWarningEval(list, ruleId);
        if (null != warningEval && warningEval.size() > 0) {
            param.getRecords().forEach(it -> {
                it.setWarningRuleEvals(warningEval);
            });
        }
        return page.setRecords(param.getRecords());
    }

    @Override
    public Page<WarningData> pending(PageVO<WarningData> page, String ruleId) {
        List<EvalItem> list = new ArrayList<>();
        PageVO<WarningData> param = baseMapper.pending(page, ruleId);
        List warningEval = getWarningEval(list, ruleId);
        if (null != warningEval && warningEval.size() > 0 && param.getRecords().size() > 0) {
            param.getRecords().forEach(it -> {
                it.setWarningRuleEvals(warningEval);
                Integer dataId = it.getDataId();
                List<WarningEvalNote> warningEvalNote = baseMapper.getWarningEvalNote(ruleId, dataId);
                it.setWarningEvalNotes(warningEvalNote);
            });
        }
        return page.setRecords(param.getRecords());
    }

    @Override
    public Integer audit(WarningData data) {
        WarningData warningData = new WarningData();
        warningData.setReportedRemark(data.getReportedRemark());
        //审核状态 3通过，2不通过
        warningData.setHandleState(data.getHandleState());
        warningData.setDataId(data.getDataId());
        int successFlag = baseMapper.updateById(warningData);
        return successFlag;
    }
}
